﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;


namespace VASJ.Service.Library.Manager
{
    public class PermissionTypeManager : BaseManager
    {
        /// <summary>
        /// Init
        /// </summary>
        /// <param name="_ApplicationName"></param>
        public PermissionTypeManager(string _ApplicationName)
            : base(_ApplicationName)
        {
        }

        /// <summary>
        /// Create permission type
        /// </summary>
        /// <param name="PermissionName"></param>
        /// <returns></returns>
        public bool CreatePermission(string PermissionName)
        {
            try
            {
                AHSPermissionType pt = new AHSPermissionType();

                pt.PermissionName = PermissionName;
                pt.ProjectType = this.ApplicationName;

                this.mdb.AHSPermissionTypes.InsertOnSubmit(pt);

                return true;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();

                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] AHSService.Library.Manager.PermissionTypeManager error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Get PermissionID by PermissionName
        /// </summary>
        /// <param name="PermissionName"></param>
        /// <returns></returns>
        public int GetPermissionID(string PermissionName)
        {
            try
            {
                var per = from p in this.mdb.AHSPermissionTypes where p.PermissionName == PermissionName select p.PermissionID;

                int PermissionID = 0;

                if (per != null && per.Count() > 0 && Int32.TryParse(per.FirstOrDefault().ToString(), out PermissionID))
                    return PermissionID;
                else
                    return 0;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.GetPermissionID {0}", ex);

                return 0;
            }
        }

        /// <summary>
        /// Add Permission for user
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="permissionID"></param>
        /// <param name="projectID"></param>
        /// <returns></returns>
        public bool AddPermissionForUser(Guid userID, int permissionID, int projectID)
        {
            try
            {
                AHSUserPermission up = new AHSUserPermission();

                up.UserID = userID;

                if (permissionID != 0) up.PermissionID = permissionID;

                up.ProjectID = projectID;

                this.mdb.AHSUserPermissions.InsertOnSubmit(up);

                this.mdb.SubmitChanges();

                return true;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] AHSService.Library.Manager.AddPermissionForUser error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Remove all permission of user for target
        /// </summary>
        /// <returns></returns>
        public bool RemovePermissionForTarget(Guid userID, int projectID, int permissionID)
        {
            try
            {
                var pft = from it in this.mdb.AHSUserPermissions
                          where it.PermissionID == permissionID && it.UserID == userID && it.ProjectID.HasValue && it.ProjectID.Value == projectID
                          select it;

                this.mdb.AHSUserPermissions.DeleteAllOnSubmit(pft);

                this.mdb.SubmitChanges();

                return true;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] AHSService.Library.Manager.RemovePermissionForTarget error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Remove all permission for user
        /// </summary>
        /// <returns></returns>
        public bool RemovePermissionForUser(Guid userID)
        {
            try
            {
                var pfu = from it in this.mdb.AHSUserPermissions
                          where it.UserID == userID && it.ProjectID.HasValue && it.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()
                          select it;

                this.mdb.AHSUserPermissions.DeleteAllOnSubmit(pfu);

                this.mdb.SubmitChanges();

                return true;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] AHSService.Library.Manager.RemovePermissionForUser error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Remove all permission for role
        /// </summary>
        /// <returns></returns>
        public bool RemovePermissionForRole(Guid roleID)
        {
            try
            {
                var rp = from it in this.mdb.AHSRolePermissions
                         where it.RoleID == roleID && it.RoleID.HasValue && it.AHSAspnetRole.AHSProjectType.ApplicationName.ToLower() == ApplicationName.ToLower()
                         select it;

                this.mdb.AHSRolePermissions.DeleteAllOnSubmit(rp);

                this.mdb.SubmitChanges();

                return true;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] AHSService.Library.Manager.RemovePermissionForRole error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Check exist permission for User in Project
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="permissionID"></param>
        /// <param name="projectID"></param>
        /// <returns></returns>
        public bool IsExistPermissionForUser(Guid userID, int permissionID, int projectID)
        {
            bool ret = false;

            try
            {
                var per = from p in this.mdb.AHSUserPermissions
                          where p.UserID.HasValue && p.UserID == userID
                          && p.PermissionID.HasValue && p.PermissionID.Value == permissionID
                          && p.ProjectID.HasValue && p.ProjectID.Value == projectID
                          select p;

                ret = (per != null && per.Count() > 0);
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] PermissionTypeManager.IsExistPermissionForUser {0}", ex);
            }

            return ret;
        }

        /// <summary>
        /// Get All permission for project
        /// </summary>
        /// <returns></returns>
        public List<string> GetAllPermission()
        {
            try
            {
                var pers = from per in this.mdb.AHSPermissionTypes
                           where per.ProjectType == this.ApplicationName
                           select per.PermissionName;

                List<string> lst_pers = new List<string>();

                foreach (var perName in pers)
                {
                    lst_pers.Add(perName);
                }

                return lst_pers;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] PermissionTypeManager.GetAllPermission {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Get permission list for role
        /// </summary>
        /// <param name="roleName"></param>
        /// <returns></returns>
        public List<string> GetPermissionListForRole(string roleName)
        {
            try
            {
                List<string> lstPermission = new List<string>();
                RoleManager rm = new RoleManager(this.ApplicationName);
                Guid roleID = rm.GetRoleID(roleName);

                var permission = (from per in this.mdb.AHSRolePermissions
                                  where per.RoleID.HasValue && per.RoleID.Value == roleID && per.AHSAspnetRole.AHSProjectType.ApplicationName.ToLower() == ApplicationName.ToLower() && per.PermissionID.HasValue
                                  select per.AHSPermissionType.PermissionName).Distinct();

                foreach (var per in permission)
                {
                    lstPermission.Add(per);
                }

                return lstPermission;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] PermissionTypeManager.GetPermissionListForRole {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Get permission list for user
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public List<string> GetRolePermissionForUser(string userName)
        {
            try
            {
                List<string> lstPermission = new List<string>();
                RoleManager rm = new RoleManager(this.ApplicationName);
                List<string> roles = rm.GetRolesForUser(userName).ToList();

                // Get permision list of user in application
                var permission = (from rp in this.mdb.AHSRolePermissions
                                  where rp.RoleID.HasValue && roles.Contains(rp.AHSAspnetRole.Rolename) && rp.PermissionID.HasValue && rp.AHSAspnetRole.AHSProjectType.ApplicationName.ToLower() == ApplicationName.ToLower()
                                  select rp.AHSPermissionType.PermissionName).Distinct();

                foreach (var per in permission)
                {
                    lstPermission.Add(per);
                }

                return lstPermission;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] PermissionTypeManager.GetRolePermissionForUser error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Get all projectid is granted a permission for user
        /// </summary>
        /// <returns></returns>
        public List<int> GetProjectsGrantedPermission(Guid userID, int permissionID)
        {
            try
            {
                List<int> lstRet = new List<int>();

                var projects = from prj in this.mdb.AHSUserPermissions
                               where prj.UserID.HasValue && prj.UserID.Value == userID && prj.PermissionID.HasValue && prj.PermissionID.Value == permissionID
                               select prj.ProjectID;

                foreach (var prj in projects)
                {
                    if (prj.HasValue) lstRet.Add(prj.Value);
                }

                return lstRet;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] PermissionTypeManager.GetProjectsGrantedPermission error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Get the userid list is granted permission in project 
        /// </summary>
        /// <returns></returns>
        public List<Guid> GetGrantedUserForProject(int projectID, int permissionID)
        {
            try
            {
                List<Guid> lstUser = new List<Guid>();

                var users = from user in this.mdb.AHSUserPermissions
                            where user.PermissionID.HasValue && user.PermissionID.Value == permissionID && user.ProjectID.HasValue && user.ProjectID.Value == projectID
                            select user.UserID;

                foreach (var user in users)
                {
                    if (user.HasValue) lstUser.Add(user.Value);
                }

                return lstUser;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] PermissionTypeManager.GetGrantedUserForProject error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Get the username list is granted permission in project 
        /// </summary>
        /// <returns></returns>
        public List<string> GetGrantedUserNameForProject(int projectID, int permissionID)
        {
            try
            {
                List<string> lstUser = new List<string>();

                var users = (from user in this.mdb.AHSUserPermissions
                             where user.PermissionID.HasValue && user.PermissionID.Value == permissionID && user.ProjectID.HasValue && user.ProjectID.Value == projectID && user.UserID.HasValue
                             select user.AHSAspnetMembership.AHSAspnetUser.Username).Distinct();

                foreach (var user in users)
                {
                    lstUser.Add(user);
                }

                return lstUser;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] PermissionTypeManager.GetGrantedUserForProject error {0}", ex);

                return null;
            }
        }

        /// <summary>
        /// Get role list of permission
        /// </summary>
        /// <returns></returns>
        public List<string> GetRoleOfPermission(int permissionID)
        {
            try
            {
                List<string> lstRole = new List<string>();

                var role = (from it in this.mdb.AHSRolePermissions
                            where it.PermissionID.HasValue && it.PermissionID.Value == permissionID && it.RoleID.HasValue
                            && it.AHSAspnetRole.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()
                            && it.AHSAspnetRole.Projecttype.HasValue
                            select it.AHSAspnetRole.Rolename).Distinct();

                foreach (var it in role)
                {
                    lstRole.Add(it);
                }

                return lstRole;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] PermissionTypeManager.GetRoleOfPermission error {0}", ex);

                return null;
            }
        }
    }
}